package com.mdd.front.controller;

import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.mdd.common.core.AjaxResult;
import com.mdd.common.enums.ClientEnum;
import com.mdd.common.utils.IpUtil;
import com.mdd.common.utils.RequestUtil;
import com.mdd.front.LikeFrontThreadLocal;
import com.mdd.front.service.IPayService;
import com.mdd.front.service.order.IRechargeOrderService;
import com.mdd.front.utils.WxPayServiceUtil;
import com.mdd.front.validate.BalancePayParam;
import com.mdd.front.vo.wxpay.WxPayCreateOrderRequest;
import nl.bitwalker.useragentutils.UserAgent;
import org.apache.commons.io.IOUtils;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

/**
 * @author panweiliang
 */
@RestController
@RequestMapping("/api/pay")
public class PayController {
    @Resource
    private IPayService payService;

    @Resource
    private IRechargeOrderService rechargeOrderService;

    public static String getServerUrl(HttpServletRequest request) {
        // 访问协议
        String agreement = request.getScheme();
        // 访问域名
        String serverName = request.getServerName();
        // 访问端口号
        int port = request.getServerPort();
        // 访问项目名
        String contextPath = request.getContextPath();
        String url = "%s://%s%s%s";
        String portStr = "";
        if (port != 80) {
            portStr += ":" + port;
        }
        return String.format(url, agreement, serverName, portStr, contextPath);
    }

    /**
     * 调用统一下单接口，并组装生成支付所需参数对象.
     *
     * @param request 统一下单请求参数
     *
     */
    @PostMapping("/wx/createOrder")
    public Object createOrder(@RequestBody WxPayCreateOrderRequest request, HttpServletRequest httpServletRequest) throws WxPayException {
        String serverUrl = getServerUrl(httpServletRequest);
        return AjaxResult.success(this.payService.createWxOrder(request, serverUrl));
    }

    /**
     * 调用统一下单接口，并组装生成支付所需参数对象.
     *
     * @param request 统一下单请求参数
     *
     */
    @PostMapping("/h5/createOrder")
    public Object createH5Order(@RequestBody WxPayCreateOrderRequest request, HttpServletRequest httpServletRequest) throws WxPayException {
        String serverUrl = getServerUrl(httpServletRequest);
        request.setPlayClientIp(IpUtil.getIpAddress());
        request.setH5InfoType(getH5InfoType());
        String h5url = this.payService.createH5Order(request, serverUrl);
        return AjaxResult.success("success", h5url);
    }

    private String getH5InfoType() {
        HttpServletRequest request = RequestUtil.handler();
        String userAgent = request.getHeader("User-Agent");
        if(userAgent.contains("Android")){//安卓手机
            return "Android";
        }else if(userAgent.contains("iPhone")||userAgent.contains("iPod")||userAgent.contains("iPad")){//苹果手机
            return "IOS";
        } else {
            return "wap";
        }
    }

    /**
     * 调用统一下单接口，并组装生成支付所需参数对象.
     *
     * @param request 统一下单请求参数
     *
     */
    @PostMapping("/wx/createRechargeOrder")
    public Object createRechargeOrder(@RequestBody WxPayCreateOrderRequest request, HttpServletRequest httpServletRequest) throws WxPayException {
        String serverUrl = getServerUrl(httpServletRequest);
        return AjaxResult.success(this.payService.createWxRechargeOrder(request, serverUrl));
    }

    @GetMapping("/wx/rechargeOrder/detail")
    public Object getRechargeOrder(@RequestParam("orderId") Integer orderId) {
        return AjaxResult.success(this.rechargeOrderService.getById(orderId));
    }


    //  支付回调通知处理
    @PostMapping("/wx/notify/order")
    public String parseOrderNotifyResult(@RequestBody String jsonData, HttpServletRequest request) throws WxPayException {
        SignatureHeader signatureHeader = this.getRequestHeader(request);
        boolean flag = this.payService.dealWxOrderNotify(jsonData, signatureHeader);;
        return flag ? WxPayNotifyResponse.success("成功") : WxPayNotifyResponse.fail("失败");
    }




    @PostMapping("/wx/notify/rechargeOrder")
    public String parseRechargeOrderNotifyResult(@RequestBody String jsonData, HttpServletRequest request) throws WxPayException {
        SignatureHeader signatureHeader = this.getRequestHeader(request);
        boolean flag = this.payService.dealWxRechargeOrderNotify(jsonData, signatureHeader);
        return flag ? WxPayNotifyResponse.success("成功") : WxPayNotifyResponse.fail("失败");
    }


    @PostMapping("/test")
    public void test() throws WxPayException {
        boolean flag = this.rechargeOrderService.updateOrderStatusToPaid("180618529659231957", "4200001751202303169430053671");
    }


    /**
     * 获取回调请求头：签名相关
     *
     * @param request HttpServletRequest
     * @return SignatureHeader
     */
    public SignatureHeader getRequestHeader(HttpServletRequest request) {
        // 获取通知签名
        String signature = request.getHeader("wechatpay-signature");
        String nonce = request.getHeader("wechatpay-nonce");
        String serial = request.getHeader("wechatpay-serial");
        String timestamp = request.getHeader("wechatpay-timestamp");

        SignatureHeader signatureHeader = new SignatureHeader();
        signatureHeader.setSignature(signature);
        signatureHeader.setNonce(nonce);
        signatureHeader.setSerial(serial);
        signatureHeader.setTimeStamp(timestamp);
        return signatureHeader;
    }

    /**
     *
     */
    @PostMapping("/balance/execute")
    public Object executeAccount(@RequestBody BalancePayParam balancePayParam) {
        Integer userId = LikeFrontThreadLocal.getUserId();
        Integer orderId = balancePayParam.getOrderId();
        Assert.notNull(orderId, "orderId不能为null");
        balancePayParam.setUserId(userId);
        this.payService.balance2PayOrder(balancePayParam);
        return AjaxResult.success();
    }


    @RequestMapping("/test")
    @ResponseBody
    public Object test(@RequestParam("terminal") String terminal) {
        WxPayService wxPayService = WxPayServiceUtil.handler(terminal);
        System.out.println(wxPayService);
        return wxPayService;
    }

}

